/*
 * Frac.cpp
 *
 *  Created on: Oct 19, 2011
 *      Author: correa
 */

#include "FracSolvers.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

double ** x;

Weight<double> * u = new Weight<double>();

class XWeight : public Weight<double> {
public:
	XWeight() {};
	~XWeight() {};

	double weight(const int i, const int j) { return x[i][j]; };
};

FracColor::~FracColor() {
}

template <>
FracColor::FracColor(Graph * g, ModelerFactory<RepModeler,Graph> * fm, int k) : RepColor(g, fm, k) {

}

template <>
FracColor::FracColor(Graph * g, ModelerFactory<ARepModeler,Graph> * fm, int k) : RepColor(g, fm, k) {

}

int branchCallback (CPXCENVptr env,
		void         *cbdata,
		int           wherefrom,
		void         *cbhandle,
		int           type,
		int           sos,
		int           nodecnt,
		int           bdcnt,
		const double *nodeest,
		const int    *nodebeg,
		const int    *indices,
		const char   *lu,
		const int    *bd,
		int          *useraction_p) {

	FracColor * fc = *((FracColor **) cbhandle);

//	CPXgetcallbacknodeobjval (env, cbdata, wherefrom, &objv);

	int j, l;
	int nreps = fc->rm->nreps();
	double *xr = new double[nreps];
	for (j = 0; j < nreps; j++) {
		fc->repm[j]->objective(u);
		CPXgetcallbacknodex (env, cbdata, wherefrom, xr, fc->repm[j]->rmatind()[0], fc->repm[j]->rmatind()[fc->repm[j]->ccnt()-1]);
		int nrd;
		const int * rd = fc->rm->rd(j, &nrd);
		for (l = 0; l < fc->repm[j]->ccnt(); l++)
			x[j][rd[l]] = xr[l];
	}

	fc->rm->objective(u);
	for (l = 0; l < fc->rm->ccnt(); l++) {
		CPXgetcallbacknodex (env, cbdata, wherefrom, xr, fc->rm->rmatind()[l], fc->rm->rmatind()[l]);
		x[l][l] = *xr;
	}
	delete xr;

	return 0;
}

int FracColor::solveByEnumeration() {
	FracColor * fc = this;
	CPXsetbranchcallbackfunc (cpxenv, branchCallback, &fc);
	CPXsetintparam(cpxenv, CPX_PARAM_NODELIM, 1);
	// no zero-half cuts
	CPXsetintparam(cpxenv, CPX_PARAM_ZEROHALFCUTS, -1);
	// no Gomory fractional cuts
	CPXsetintparam(cpxenv, CPX_PARAM_FRACCUTS, -1);
	// no implied bounds cuts
	CPXsetintparam(cpxenv, CPX_PARAM_IMPLBD, -1);

	x = new double*[n];

	int i, j;
	for (i = 0; i < n; i++) {
		x[i] = new double[n];
		for (j = 0; j < n; j++)
			x[i][j] = 0.0;
	}

	Stab::solveByEnumeration();

	int *rank;
	int *Ri=NULL;
	int r;
	int err;

	Weight<double> * w = new XWeight();

	err = WGraphs<double>::dsaturFracColoringSort(rm->graph(), w, &r, &Ri,23434,&rank);

	printf("Number of Cliques = %d.\n", err);

	delete w;
	delete x;
	delete Ri;
	delete rank;

	return 0;
}

